define(['app', 'json5', 'clipboard', 'jquery.format'], function(app, JSON5, Clipboard) {
    app.controller('TestMockController', function($http, $timeout, $scope, $compile, xContext, $uibModalInstance,
            xDialog, toastr) {
        var self = this;
        self.url = '';
        self.method = 'GET';
        self.files = [];
        self.response = null;
        self.parsable = true;
        self.completed = true;

        var host = null;
        var body = null;
        var jsonEditor = null;
        self.fullScreen = false;
        self.fullScreen2 = false;

        function subMatch(string, regex) {
            var result = regex.exec(string);
            if (result != null && result.length >= 2) {
                return result[1];
            }
            return '';
        }

        self.init = function() {
            var path = subMatch(xContext.data, /URL：(.*)/gi);
            if (path != '') {
                xContext.path = path;
            }
            self.url = xContext.host + xContext.path;

            self.method = subMatch(xContext.data, /Method：(get|post)/gi).toUpperCase();
            self.method = (self.method == '' ? 'GET' : self.method);

            var request = subMatch(xContext.data, /入参：([\s\S]*)出参：/gm).trim();

            var maxHeight = 150;
            // json editor
            jsonEditor = ace.edit('json-request');
            jsonEditor.getSession().setMode("ace/mode/hjson");
            jsonEditor.setOptions({
                fontSize: 12,
                showGutter: false,
                showLineNumbers: false,
                maxPixelHeight: maxHeight,
                showPrintMargin: false,
                autoScrollEditorIntoView: true,
                enableBasicAutocompletion: true,
                enableSnippets: true,
                enableLiveAutocompletion: true
            });
            jsonEditor.setValue('/*支持JSON的对象格式与注释*/\n');
            jsonEditor.on('change', function(e) {
                var newValue = jsonEditor.getValue();
                self.parsable = true;
                if (newValue !== '') {
                    try {
                        body = JSON5.parse(newValue);
                    } catch (err) {
                        try {
                            JSON5.parse(newValue + '\n{}');
                        } catch (ex) {
                            self.parsable = false;
                        }
                    }
                }
                $timeout(function() { $scope.$apply(); });
            });
            // add request body
            jsonEditor.gotoLine(2);
            jsonEditor.insert(request);

            // data viewer
            dataViewer = ace.edit('json-response');
            dataViewer.getSession().setMode("ace/mode/text");
            dataViewer.setOptions({
                fontSize: 12,
                //wrap: true,
                readOnly: true,
                showGutter: false,
                showLineNumbers: false,
                showPrintMargin: false,
                highlightActiveLine: false,
                autoScrollEditorIntoView: true
            });

            // request body tools
            jQuery('#json-request .ace_scroller').append($compile(jQuery('#json-tools').html())($scope));
            // response body tools
            jQuery('#json-response .ace_scroller').append($compile(jQuery('#view-tools').html())($scope));
            // disable click event of tools
            jQuery('.x-editor-tool').mousedown(function(e) { return false; });
            // full screen
            var dlgMockTest = jQuery('[name="frmMock"]').parents('.modal-dialog');
            var resizeTextViewer = function(fullScreen) {
                if (fullScreen) {
                    dlgMockTest.css('height', dlgMockTest.height());
                } else {
                    dlgMockTest.css('height', '');
                }
            }
            $scope.$watch('dvm.fullScreen', function(fullScreen) {
                resizeTextViewer(fullScreen);
                setTimeout(function() {
                    jsonEditor.setOption('maxPixelHeight', (fullScreen ? dlgMockTest.height() - 60 : maxHeight));
                    jsonEditor.resize();
                }, 50);
            });
            $scope.$watch('dvm.fullScreen2', function(fullScreen) {
                resizeTextViewer(fullScreen);
                setTimeout(function() {
                    dataViewer.setOption('maxPixelHeight', (fullScreen ? dlgMockTest.height() - 60 : maxHeight));
                    dataViewer.resize();
                }, 50);
            });

            jQuery('#json-request, #json-response').height(maxHeight);

            $scope.$watch('dvm.method', function(newValue) {
                if (newValue == 'POST') {
                    jsonEditor.focus();
                }
            });

            $scope.$watch('dvm.response', function(newValue) {
                if (newValue == null) {
                    dataViewer.setValue('', -1);
                } else {
                    var modeId = 'ace/mode/' + newValue.mode;
                    if (modeId != dataViewer.getSession().getMode().$id) {
                        dataViewer.getSession().setMode(modeId);
                    }
                    dataViewer.setValue(newValue.data, -1);
                }
                dataViewer.resize();
            });

            new Clipboard('#copy-response', {
                text: function() {
                    return dataViewer.getValue();
                }
            }).on('success', function(e) {
                toastr.success('已复制到剪贴板！');
            });
        }

        self.send = function(valid) {
            self.response = null;
            if (valid) {
                // parse host
                var matches = self.url.match(/^http(s)?:\/\/[\w-\.]+(:\d+)?/);
                if (!_.isEmpty(matches)) {
                    host = matches[0];
                }
                // send request
                if (self.method == 'GET' || self.parsable) {
                    self.completed = false;
                    $http({
                        url: '/mock/test/send',
                        method: 'POST',
                        headers: {
                            'Pragma': 'no-cache',
                            'Cache-Control': 'no-cache',
                            'Content-Type': 'application/json;charset=UTF-8'
                        },
                        timeout: 30000,
                        data: {
                            url: self.url,
                            method: self.method,
                            data: (self.method == 'POST' && body != null ? body : null)
                        },
                        transformResponse: function(response) {
                            return response;
                        }
                    }).then(function(response) {
                        self.completed = true;
                        if (response.status >= 400 && response.data == '') {
                            xDialog.alert('错误信息', '服务器的返回信息：' + response.statusText);
                        } else {
                            var contentType = response.headers('Content-Type');
                            if (contentType != null && contentType.indexOf('application/json') > -1) {
                                self.response = {
                                    mode: 'json',
                                    data: jQuery.format(response.data, { method: 'json' })
                                };
                            } else {
                                self.response = { mode: 'text', data: response.data };
                            }
                        }
                    }, function(response) {
                        self.completed = true;
                    });
                    toastr.success('测试请求已发送！');
                }
            }
        }

        self.close = function() {
            $uibModalInstance.close({ host: host });
        }
    });
});
